﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;

namespace Nomad.WebSync.Pocket.Sync {
    class Tasks : SynchronizationControl {
        public Tasks() : base() { }

        public override void Start() {
            var remoteList = this.Service.GetTasks();
            var localList = this.Session.GetDefaultFolder(PocketOutlook.OlDefaultFolders.olFolderTasks);
            var count = remoteList.Count() + localList.Items.Count;
            var index = 1;

            foreach (var remote in remoteList) {
                this.DoProgressChanged(index++, count);

                if (remote.State == (byte)States.InsertOnMobile) {
                    this.insertLocal(remote);
                    continue;
                }

                if (remote.State == (byte)States.UpdateOnMobile) {
                    this.updateLocal(remote);
                    continue;
                }

                if (remote.State == (byte)States.RemoveFromMobile) {
                    this.removeLocal(remote);
                    continue;
                }

                var local = this.getLocal(remote.oid);
                if (local == null) {
                    this.removeRemote(remote);
                    continue;
                }

                if (local.IsChanged(remote)) {
                    this.updateRemote(local, remote);
                    continue;
                }
            }

            foreach (var item in localList.Items) {
                this.DoProgressChanged(index++, count);

                var local = (PocketOutlook.ITask)item;
                var remote = remoteList.SingleOrDefault(query => query.oid == local.oid);
                if (remote == null)
                    this.insertRemote(local);
            }
        }

        private PocketOutlook.ITask getLocal(int oid) {
            try {
                return (PocketOutlook.ITask)this.Session.GetItemFromOid(oid);
            } catch {
                return null;
            }
        }
        private PocketOutlook.ITask createNew() {
            return (PocketOutlook.ITask)this.Session.CreateItem((int)PocketOutlook.OlItemType.olTaskItem);
        }

        private void insertLocal(WebSyncService.Task remote) {
            var local = this.createNew();
            local.FromService(remote);
            local.Save();

            remote.oid = local.oid;
            this.Service.UpdateTask(remote);
        }
        private void updateLocal(WebSyncService.Task remote) {
            var local = this.getLocal(remote.oid);
            if (local == null) {
                this.insertLocal(remote);
            } else {
                local.FromService(remote);
                local.Save();
                this.Service.UpdateTask(remote);
            }
        }
        private void removeLocal(WebSyncService.Task remote) {
            var local = this.getLocal(remote.oid);
            if (local != null) local.Delete();
            this.Service.RemoveTask(remote);
        }

        private void insertRemote(PocketOutlook.ITask local) {
            this.updateRemote(local, new WebSyncService.Task());
        }
        private void updateRemote(PocketOutlook.ITask local, WebSyncService.Task remote) {
            remote.FromMobile(local);
            this.Service.UpdateTask(remote);
        }
        private void removeRemote(WebSyncService.Task remote) {
            this.Service.RemoveTask(remote);
        }
    }

    static class TasksExtensions {
        public static bool IsChanged(this PocketOutlook.ITask mobile, WebSyncService.Task service) {
            if (service.Body == mobile.Body) return true;
            if (service.Categories == mobile.Categories) return true;
            if (service.Complete == mobile.Complete) return true;
            if (service.DateCompleted == mobile.DateCompleted) return true;
            if (service.DueDate == mobile.DueDate) return true;
            if (service.Importance == (byte)mobile.Importance) return true;
            if (service.oid == mobile.oid) return true;
            if (service.ReminderOptions == (byte)mobile.ReminderOptions) return true;
            if (service.ReminderSet == mobile.ReminderSet) return true;
            if (service.ReminderSoundFile == mobile.ReminderSoundFile) return true;
            if (service.ReminderTime == mobile.ReminderTime) return true;
            if (service.Sensitivity == (byte)mobile.Sensitivity) return true;
            if (service.StartDate == mobile.StartDate) return true;
            if (service.Subject == mobile.Subject) return true;
            if (service.TeamTask == mobile.TeamTask) return true;

            return false;
        }

        public static void FromService(this PocketOutlook.ITask mobile, WebSyncService.Task service) {
            mobile.Body = service.Body;
            mobile.Categories = service.Categories;
            mobile.Complete = service.Complete;
            mobile.DueDate = service.DueDate;
            mobile.Importance = (PocketOutlook.OlImportance)service.Importance;
            mobile.ReminderOptions = (PocketOutlook.OlReminderOptions)service.ReminderOptions;
            mobile.ReminderSet = service.ReminderSet;
            mobile.ReminderSoundFile = service.ReminderSoundFile;
            mobile.ReminderTime = service.ReminderTime;
            mobile.Sensitivity = (PocketOutlook.OlSensitivity)service.Sensitivity;
            mobile.StartDate = service.StartDate;
            mobile.Subject = service.Subject;
            mobile.TeamTask = service.TeamTask;
        }

        public static void FromMobile(this WebSyncService.Task service, PocketOutlook.ITask mobile) {
            service.Body = mobile.Body;
            service.Categories = mobile.Categories;
            service.Complete = mobile.Complete;
            service.DateCompleted = mobile.DateCompleted;
            service.DueDate = mobile.DueDate;
            service.Importance = (byte)mobile.Importance;
            service.oid = mobile.oid;
            service.ReminderOptions = (byte)mobile.ReminderOptions;
            service.ReminderSet = mobile.ReminderSet;
            service.ReminderSoundFile = mobile.ReminderSoundFile;
            service.ReminderTime = mobile.ReminderTime;
            service.Sensitivity = (byte)mobile.Sensitivity;
            service.StartDate = mobile.StartDate;
            service.Subject = mobile.Subject;
            service.TeamTask = mobile.TeamTask;
        }
    }
}
